package com.hongkuncheng.cms.controller.admin;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Subqueries;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Controller;
import com.hongkuncheng.cms.controller.BaseController;
import com.hongkuncheng.cms.helper.DataHelper;
import com.hongkuncheng.cms.helper.PageHelper;
import com.hongkuncheng.cms.model.Admin;
import com.hongkuncheng.cms.model.Checkflow;
import com.hongkuncheng.cms.model.Checknode;
import com.hongkuncheng.cms.model.ChecknodeReAdmin;
import com.hongkuncheng.cms.model.ChecknodeType;
import com.hongkuncheng.cms.model.Department;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 审核节点管理
 *
 * @author 洪坤成
 */
@Controller
@Transactional
@RequestMapping("admin/checknode")
public class AchecknodeController extends BaseController {

    // 审核流程节点列表
    @RequestMapping
    public String index() {
        int checkflowId = Integer.parseInt(request.getParameter("checkflowid"));
        Checkflow checkflow = factorySession.get(Checkflow.class, checkflowId);
        request.setAttribute("checkflow", checkflow);
        List<Checknode> checknodes = factorySession.createCriteria(Checknode.class)
                .add(Restrictions.eq("checkflow.id", checkflowId))
                .addOrder(Order.asc("sort")).list();
        request.setAttribute("checknodes", checknodes);
        return view();
    }

    // 审核流程节点编辑
    @RequestMapping("edit")
    public String edit() {
        int checkflowId = Integer.parseInt(request.getParameter("checkflowid"));
        Checkflow checkflow = factorySession.get(Checkflow.class, checkflowId);
        request.setAttribute("checkflow", checkflow);
        int checknodeId = request.getParameter("checknodeid") == null ? 0 :
                Integer.parseInt(request.getParameter("checknodeid"));
        Checknode checknode = checknodeId == 0 ? new Checknode() : factorySession.get(Checknode.class, checknodeId);
        if (checknodeId == 0) {
            checknode.setSingleaudit(true);
            checknode.setCanedit(true);
            checknode.setGroupbydepart(true);
        }
        request.setAttribute("checknode", checknode);
        Criteria criteriaDepartment = factorySession.createCriteria(Department.class, "this_");
        DetachedCriteria criteriaAdmin = DetachedCriteria.forClass(Admin.class, "admin");
        criteriaAdmin.setProjection(Projections.property("department"));
        criteriaAdmin.add(Property.forName("department.id").eqProperty("this_.id"));
        List<Department> departments = criteriaDepartment.add(Subqueries.exists(criteriaAdmin))
                .addOrder(Order.asc("sort")).list();
        request.setAttribute("departments", departments);
        // 节点已参与的审核人员ID集合
        List<Integer> adminIds = new ArrayList<Integer>();
        if (checknodeId > 0)
            for (ChecknodeReAdmin cra : checknode.getChecknodeReAdmins())
                adminIds.add(cra.getAdmin().getId());
        request.setAttribute("adminids", adminIds);
        return view();
    }

    // 审核流程节点编辑处理
    @RequestMapping("editdo")
    @ResponseBody
    public void editdo() {
        checkAdminPermission("yunwei_systemsetup_checkflow");
        int checkflowId = Integer.parseInt(request.getParameter("checkflowid"));
        int checknodeId = Integer.parseInt(request.getParameter("checknodeid"));
        String name = request.getParameter("name");
        int exist = Integer.parseInt(factorySession.createCriteria(Checknode.class)
                .add(Restrictions.eq("name", name)).add(Restrictions.ne("id", checknodeId))
                .add(Restrictions.eq("checkflow.id", checkflowId))
                .setProjection(Projections.count("id")).uniqueResult().toString());
        if (exist > 0) {
            PageHelper.alertAndGoBack("节点名称已存在，请重新输入");
            return;
        }
        Checkflow checkflow = factorySession.get(Checkflow.class, checkflowId);
        Checknode checknode = checknodeId == 0 ? new Checknode() :
                factorySession.load(Checknode.class, checknodeId, LockMode.PESSIMISTIC_WRITE);
        checknode.setCheckflow(checkflow);
        checknode.setName(name);
        checknode.setSingleaudit(Boolean.parseBoolean(request.getParameter("singleaudit")));
        checknode.setCanedit(Boolean.parseBoolean(request.getParameter("canedit")));
        checknode.setGroupbydepart(Boolean.parseBoolean(request.getParameter("groupbyDepart")));
        List<Integer> adminIds = DataHelper.convertToIntegerList(request.getParameterValues("adminids"));
        if (checknodeId == 0) {
            // 当前最大排序值
            Object uniqueResult = factorySession.createCriteria(Checknode.class)
                    .add(Restrictions.eq("checkflow.id", checkflowId))
                    .setProjection(Projections.max("sort")).uniqueResult();
            int maxSort = uniqueResult == null ? 0 : Integer.parseInt(uniqueResult.toString());
            checknode.setSort(++maxSort);
            checknode.setChecknodeType(factorySession.load(ChecknodeType.class, 2));
            factorySession.save(checknode);
            recordLog("新建审核流程节点《" + checknode.getName().trim() + "》");
        } else {
            if (checknode.getChecknodeReAdmins().size() > 0) {
                // 删除原来的映射关系
                List<Object> cras = new ArrayList<>();
                for (ChecknodeReAdmin cra : checknode.getChecknodeReAdmins()) {
                    if (!adminIds.contains(cra.getAdmin().getId())) cras.add(cra);
                    else adminIds.remove(Integer.valueOf(cra.getAdmin().getId()));
                }
                factorySession.delete(cras);
            }
            recordLog("修改审核流程节点《" + checknode.getName().trim() + "》");
        }
        if (adminIds.size() > 0) {
            // 创建新的映射关系
            List<Admin> admins = factorySession.createCriteria(Admin.class)
                    .add(Restrictions.in("id", adminIds)).list();
            for (Admin admin : admins) {
                ChecknodeReAdmin cra = new ChecknodeReAdmin();
                cra.setChecknode(checknode);
                cra.setAdmin(admin);
                factorySession.save(cra);
            }
        }
        PageHelper.alertAndRedirect("保存成功", "./?checkflowid=" + checkflowId);
    }

    // 审核流程节点顺序切换
    @RequestMapping("switchsort")
    @ResponseBody
    public void switchsort() throws Exception {
        checkAdminPermission("yunwei_systemsetup_checkflow");
        int checkflowId = Integer.parseInt(request.getParameter("checkflowid"));
        int checknodeId = Integer.parseInt(request.getParameter("checknodeid"));
        int rate = Integer.parseInt(request.getParameter("rate")); // 增量
        Checknode checknode = factorySession.load(Checknode.class, checknodeId, LockMode.PESSIMISTIC_WRITE);
        int sortOther = checknode.getSort() + rate;
        Checknode checknodeOther = (Checknode) factorySession.createCriteria(Checknode.class)
                .add(Restrictions.eq("checkflow.id", checkflowId))
                .add(Restrictions.eq("sort", sortOther))
                .setLockMode(LockMode.PESSIMISTIC_WRITE).uniqueResult();
        checknode.setSort(checknode.getSort() + rate);
        checknodeOther.setSort(checknodeOther.getSort() - rate);
        recordLog("修改审核流程节点《" + checknode.getName().trim() + "》的排列顺序");
        response.sendRedirect("./?checkflowid=" + checkflowId);
    }

    // 审核流程节点删除
    @RequestMapping("delete")
    @ResponseBody
    public void delete() {
        checkAdminPermission("yunwei_systemsetup_checkflow");
        int checkflowId = Integer.parseInt(request.getParameter("checkflowid"));
        int checknodeId = Integer.parseInt(request.getParameter("checknodeid"));
        Checknode checknode = factorySession.load(Checknode.class, checknodeId, LockMode.PESSIMISTIC_WRITE);
        factorySession.delete(checknode);
        List<Checknode> checknodeNexts = factorySession.createCriteria(Checknode.class)
                .add(Restrictions.eq("checkflow.id", checkflowId))
                .add(Restrictions.lt("sort", checknode.getSort()))
                .setLockMode(LockMode.PESSIMISTIC_WRITE).list();
        // 循环将排序值大于当前节点的所有节点排序值自减1
        for (Checknode checknodeNext : checknodeNexts) checknodeNext.setSort(checknodeNext.getSort() - 1);
        PageHelper.alertAndRedirect("删除成功", "./?checkflowid=" + checkflowId);
    }

}
